package com.w3c.pragmatic.handler;

import cn.hutool.core.util.StrUtil;
import com.w3c.pragmatic.common.enums.ErrorTypeEnum;
import com.w3c.pragmatic.common.exception.BusinessException;
import com.w3c.pragmatic.domain.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局统一异常 @RestControllerAdvice和@ControllerAdvice区别
 *
 * <p> 1、相同点：@RestControllerAdvice和@ControllerAdvice是Spring框架中用于处理全局异常的两个注解，它们都提供了对控制器（Controller）层进行全局异常处理的便捷方式；
 * <p> 2、不同点：
 * <p>    默认情况下，@ControllerAdvice方法返回的是视图名称或ModelAndView对象。如果需要返回JSON数据，需要配合@ResponseBody注解。
 * <p>    @RestControllerAdvice是@ControllerAdvice和@ResponseBody的组合注解，专为RESTful服务设计。它默认将方法的返回值序列化为JSON或XML格式。
 *
 * @author wangdong
 * @since 2025/3/10 14:10
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {


    // 处理业务异常
    @ExceptionHandler(value = BusinessException.class)
    public Response<String> handleBusinessException(BusinessException e) {
        log.error("业务处理错误:", e);
        String errCode = StrUtil.blankToDefault(e.getCode(), ErrorTypeEnum.SYSTEM_UNKNOWN_ERROR.getErrCode());
        String errMsg = StrUtil.blankToDefault(e.getMessage(), ErrorTypeEnum.SYSTEM_UNKNOWN_ERROR.getErrMsg());
        return Response.failed(null, errCode, errMsg);
    }

    // 参数校验异常
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Response<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error("参数校验错误:", e);
        String errCode = StrUtil.blankToDefault(null, ErrorTypeEnum.METHOD_ARGUMENT_NOT_VALID_EXCEPTION.getErrCode());
        String errMsg = StrUtil.blankToDefault(e.getMessage(), ErrorTypeEnum.SYSTEM_UNKNOWN_ERROR.getErrMsg());
        return Response.failed(errCode, errMsg);
    }

    // 兜底所有异常 | 错误
    @ExceptionHandler({Exception.class, Throwable.class})
    public Response<String> handleException(Exception e) {
        log.error("系统未知错误:", e);
        return Response.failed(ErrorTypeEnum.SYSTEM_UNKNOWN_ERROR.getErrCode(), ErrorTypeEnum.SYSTEM_UNKNOWN_ERROR.getErrMsg());
    }
}
